<?php
/*
 * @Description  : Token
 * @Author       : https://github.com/skyselang
 * @Date         : 2020-05-05
 * @LastEditTime : 2020-12-25
 */

namespace app\wx\service;

use think\facade\Config;
use Firebase\JWT\JWT;
use Exception;
use app\common\cache\RedisPublic;

class AdminTokenService
{
    /**
     * Token生成
     * 
     * @param array $admin_user 用户数据
     * 
     * @return string
     */
    public static function create($admin_user = [])
    {
        $admin_token   = Config::get('admin.token');
        $key = $admin_token['key'];       //密钥
        $iss = $admin_token['iss'];                  //签发者
        $iat = time();                               //签发时间
        $nbf = time();                               //生效时间
        $exp = time() + $admin_token['exp'] * 3600;  //过期时间
        $data = [
            'id'         => $admin_user['id'],
            'login_time' => $admin_user['login_time'],
            'login_ip'   => $admin_user['login_ip']
        ];
        $payload = [
            'iss'  => $iss,
            'iat'  => $iat,
            'nbf'  => $nbf,
            'exp'  => $exp,
            'data' => $data,
        ];
        $token = JWT::encode($payload, $key);        
        return $token;
    }

    /**
     * Token验证
     *
     * @param string  $token         token
     * @param integer $admin_id      用户id
     * 
     * @return json
     */
    public static function verify($token, $admin_id = 0)
    {
        try {
            //token校验
            $key    = Config::get('admin.token.key');
            $decode = JWT::decode($token, $key, array('HS256'));
            if(empty($decode)) throw new Exception("Token解析为空");
            $admin_user_id_token = $decode->data->id;
            if ($admin_id != $admin_user_id_token) throw new Exception ('账号请求信息错误', 401);
            //redis信息二次校验
            $loginInfo = RedisPublic::setRedisTable('login')->get($admin_id);
            if(!$loginInfo || $loginInfo == '') throw new Exception ('用户token过期！', 401); 
            $loginInfo = json_decode($loginInfo,true);
            if(time() - $loginInfo['time'] > Config::get('admin.login_exp')) throw new Exception("登陆时间过期！");
            if($loginInfo['token'] != $token) throw new Exception('用户已经在别处登陆',401);
        } catch (\Exception $e) {
            exception($e->getMessage(), 401);
        }
    }
}
